package org.tamal.jsf;

import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import javax.faces.application.Application;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

import org.tamal.SessionKey;

/**
 * This listener sets the user locale.
 * @author Tamal Kanti Nath
 */
public final class LocaleListener implements PhaseListener {

    private static final long serialVersionUID = 4786862036331790014L;

    /**
     * This method will set the locale.
     */
    @Override
    public void beforePhase(PhaseEvent event) {
        FacesContext context = event.getFacesContext();
        UIViewRoot view = context.getViewRoot();
        ExternalContext ext = context.getExternalContext();
        Map<String, Object> session = ext.getSessionMap();
        Locale locale = (Locale) session.get(SessionKey.LOCALE);
        if (locale != null) {
            //view.getLocale();
            view.setLocale(locale);
            return;
        }
        Application app = context.getApplication();
    	Iterator<Locale> locales = app.getSupportedLocales();
    	while (locales.hasNext()) {
    		if (locales.next().equals(ext.getRequestLocale())) {
    			view.setLocale(ext.getRequestLocale());
    			session.put(SessionKey.LOCALE.name(), ext.getRequestLocale());
    			return;
    		}
    	}
        Iterator<Locale> requestLocales = ext.getRequestLocales();
        while (requestLocales.hasNext()) {
        	locale = requestLocales.next();
        	locales = app.getSupportedLocales();
        	while (locales.hasNext()) {
        		if (locale.equals(locales.next())) {
        			view.setLocale(locale);
        			session.put(SessionKey.LOCALE.name(), locale);
        			return;
        		}
        	}
        }
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        // Empty
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

}
